ํ ํฐ ๋ฒํท ์๊ณ ๋ฆฌ์ฆ์ ์ฌ์ฉํ API ์๋ ์ ํ ๊ตฌํ ๊ฐ์ด๋์ ๋๋ค. ๊ธ๋ก๋ฒ ์ ํ๋ฆฌ์ผ์ด์ ์ ์ํ ์ธ๋ถ ์ฌํญ๊ณผ ๊ณ ๋ ค ์ฌํญ์ ํ์ธํ์ธ์.
API ์๋ ์ ํ: ํ ํฐ ๋ฒํท ์๊ณ ๋ฆฌ์ฆ ๊ตฌํํ๊ธฐ
์ค๋๋ ๊ณผ ๊ฐ์ด ์ํธ ์ฐ๊ฒฐ๋ ์ธ์์์ API(Application Programming Interfaces)๋ ์๋ง์ ์ ํ๋ฆฌ์ผ์ด์ ๊ณผ ์๋น์ค์ ์ค์ถ์ ๋๋ค. API๋ ์๋ก ๋ค๋ฅธ ์ํํธ์จ์ด ์์คํ ์ด ์ํํ๊ฒ ํต์ ํ๊ณ ๋ฐ์ดํฐ๋ฅผ ๊ตํํ ์ ์๋๋ก ํฉ๋๋ค. ํ์ง๋ง API์ ์ธ๊ธฐ์ ์ ๊ทผ์ฑ์ ๋จ์ฉ๊ณผ ๊ณผ๋ถํ์ ๊ฐ๋ฅ์ฑ์๋ ๋ ธ์ถ๋ฉ๋๋ค. ์ ์ ํ ๋ณดํธ ์ฅ์น๊ฐ ์๋ค๋ฉด API๋ ์๋น์ค ๊ฑฐ๋ถ(DoS) ๊ณต๊ฒฉ, ๋ฆฌ์์ค ๊ณ ๊ฐ, ์ ๋ฐ์ ์ธ ์ฑ๋ฅ ์ ํ์ ์ทจ์ฝํด์ง ์ ์์ต๋๋ค. ๋ฐ๋ก ์ด ์ง์ ์์ API ์๋ ์ ํ์ด ์ค์ํ ์ญํ ์ ํฉ๋๋ค.
์๋ ์ ํ์ ํด๋ผ์ด์ธํธ๊ฐ ํน์ ๊ธฐ๊ฐ ๋ด์ ํ ์ ์๋ ์์ฒญ ์๋ฅผ ์ ์ดํ์ฌ API๋ฅผ ๋ณดํธํ๋ ํต์ฌ ๊ธฐ์ ์ ๋๋ค. ์ด๋ ๊ณต์ ํ ์ฌ์ฉ์ ๋ณด์ฅํ๊ณ , ๋จ์ฉ์ ๋ฐฉ์งํ๋ฉฐ, ๋ชจ๋ ์ฌ์ฉ์๋ฅผ ์ํด API์ ์์ ์ฑ๊ณผ ๊ฐ์ฉ์ฑ์ ์ ์งํ๋ ๋ฐ ๋์์ด ๋ฉ๋๋ค. ์๋ ์ ํ์ ๊ตฌํํ๊ธฐ ์ํ ๋ค์ํ ์๊ณ ๋ฆฌ์ฆ์ด ์์ผ๋ฉฐ, ๊ทธ์ค ๊ฐ์ฅ ์ธ๊ธฐ ์๊ณ ํจ๊ณผ์ ์ธ ๊ฒ ์ค ํ๋๊ฐ ํ ํฐ ๋ฒํท ์๊ณ ๋ฆฌ์ฆ์ ๋๋ค.
ํ ํฐ ๋ฒํท ์๊ณ ๋ฆฌ์ฆ์ด๋ ๋ฌด์์ธ๊ฐ?
ํ ํฐ ๋ฒํท ์๊ณ ๋ฆฌ์ฆ์ ๊ฐ๋ ์ ์ผ๋ก๋ ๊ฐ๋จํ์ง๋ง ๊ฐ๋ ฅํ ์๋ ์ ํ ์๊ณ ๋ฆฌ์ฆ์ ๋๋ค. ํน์ ์์ ํ ํฐ์ ๋ด์ ์ ์๋ ๋ฒํท์ ์์ํด ๋ณด์ธ์. ํ ํฐ์ ๋ฏธ๋ฆฌ ์ ํด์ง ์๋๋ก ๋ฒํท์ ์ถ๊ฐ๋ฉ๋๋ค. ๋ค์ด์ค๋ ๊ฐ API ์์ฒญ์ ๋ฒํท์์ ํ ํฐ ํ๋๋ฅผ ์๋นํฉ๋๋ค. ๋ฒํท์ ์ถฉ๋ถํ ํ ํฐ์ด ์์ผ๋ฉด ์์ฒญ์ด ํ์ฉ๋ฉ๋๋ค. ๋ฒํท์ด ๋น์ด ์์ผ๋ฉด(์ฆ, ์ฌ์ฉ ๊ฐ๋ฅํ ํ ํฐ์ด ์์ผ๋ฉด) ์์ฒญ์ ๊ฑฐ๋ถ๋๊ฑฐ๋ ํ ํฐ์ด ์ฌ์ฉ ๊ฐ๋ฅํด์ง ๋๊น์ง ๋๊ธฐ์ด์ ์ถ๊ฐ๋ฉ๋๋ค.
์ฃผ์ ๊ตฌ์ฑ ์์๋ ๋ค์๊ณผ ๊ฐ์ต๋๋ค:
- ๋ฒํท ํฌ๊ธฐ (์ฉ๋): ๋ฒํท์ด ๋ด์ ์ ์๋ ์ต๋ ํ ํฐ ์์ ๋๋ค. ์ด๋ ๋ฒ์คํธ(burst) ์ฉ๋, ์ฆ ๊ฐ์์ค๋ฌ์ด ์์ฒญ ๊ธ์ฆ์ ์ฒ๋ฆฌํ ์ ์๋ ๋ฅ๋ ฅ์ ๋ํ๋ ๋๋ค.
- ํ ํฐ ๋ณด์ถฉ ์๋: ๋ฒํท์ ํ ํฐ์ด ์ถ๊ฐ๋๋ ์๋๋ก, ์ผ๋ฐ์ ์ผ๋ก ์ด๋น ํ ํฐ ์ ๋๋ ๋ถ๋น ํ ํฐ ์๋ก ์ธก์ ๋ฉ๋๋ค. ์ด๋ ํ๊ท ์๋ ์ ํ์ ์ ์ํฉ๋๋ค.
- ์์ฒญ: ๋ค์ด์ค๋ API ์์ฒญ์ ๋๋ค.
์๋ ๋ฐฉ์:
- ์์ฒญ์ด ๋์ฐฉํ๋ฉด ์๊ณ ๋ฆฌ์ฆ์ ๋ฒํท์ ํ ํฐ์ด ์๋์ง ํ์ธํฉ๋๋ค.
- ๋ฒํท์ ํ ํฐ์ด ํ๋ ์ด์ ์์ผ๋ฉด ์๊ณ ๋ฆฌ์ฆ์ ํ ํฐ ํ๋๋ฅผ ์ ๊ฑฐํ๊ณ ์์ฒญ์ ํ์ฉํฉ๋๋ค.
- ๋ฒํท์ด ๋น์ด ์์ผ๋ฉด ์๊ณ ๋ฆฌ์ฆ์ ์์ฒญ์ ๊ฑฐ๋ถํ๊ฑฐ๋ ๋๊ธฐ์ด์ ์ถ๊ฐํฉ๋๋ค.
- ํ ํฐ์ ๋ฏธ๋ฆฌ ์ ์๋ ๋ณด์ถฉ ์๋์ ๋ฐ๋ผ ๋ฒํท์ ์ต๋ ์ฉ๋๊น์ง ์ถ๊ฐ๋ฉ๋๋ค.
ํ ํฐ ๋ฒํท ์๊ณ ๋ฆฌ์ฆ์ ์ ํํ๋ ์ด์
ํ ํฐ ๋ฒํท ์๊ณ ๋ฆฌ์ฆ์ ๊ณ ์ ์๋์ฐ ์นด์ดํฐ๋ ์ฌ๋ผ์ด๋ฉ ์๋์ฐ ์นด์ดํฐ์ ๊ฐ์ ๋ค๋ฅธ ์๋ ์ ํ ๊ธฐ์ ์ ๋นํด ๋ช ๊ฐ์ง ์ฅ์ ์ ์ ๊ณตํฉ๋๋ค:
- ๋ฒ์คํธ ์ฉ๋: ๋ฒํท ํฌ๊ธฐ๊น์ง์ ์์ฒญ ๋ฒ์คํธ๋ฅผ ํ์ฉํ์ฌ, ๊ฐํ์ ์ธ ํธ๋ํฝ ๊ธ์ฆ์ ํฌํจํ๋ ํฉ๋ฒ์ ์ธ ์ฌ์ฉ ํจํด์ ์์ฉํ ์ ์์ต๋๋ค.
- ๋ถ๋๋ฌ์ด ์๋ ์ ํ: ๋ณด์ถฉ ์๋๋ ํ๊ท ์์ฒญ๋ฅ ์ด ์ ์๋ ํ๋ ๋ด์ ๋จธ๋ฌผ๋๋ก ๋ณด์ฅํ์ฌ ์ง์์ ์ธ ๊ณผ๋ถํ๋ฅผ ๋ฐฉ์งํฉ๋๋ค.
- ๊ตฌ์ฑ ์ฉ์ด์ฑ: ๋ฒํท ํฌ๊ธฐ์ ๋ณด์ถฉ ์๋๋ฅผ ์ฝ๊ฒ ์กฐ์ ํ์ฌ ๋ค์ํ API๋ ์ฌ์ฉ์ ๋ฑ๊ธ์ ๋ง๊ฒ ์๋ ์ ํ ๋์์ ๋ฏธ์ธ ์กฐ์ ํ ์ ์์ต๋๋ค.
- ๋จ์์ฑ: ์๊ณ ๋ฆฌ์ฆ์ด ๋น๊ต์ ์ดํดํ๊ณ ๊ตฌํํ๊ธฐ ์ฌ์ ๋ง์ ์๋๋ฆฌ์ค์์ ์ค์ฉ์ ์ธ ์ ํ์ด ๋ฉ๋๋ค.
- ์ ์ฐ์ฑ: IP ์ฃผ์, ์ฌ์ฉ์ ID, API ํค ๋๋ ๊ธฐํ ๊ธฐ์ค์ ๋ฐ๋ฅธ ์๋ ์ ํ์ ํฌํจํ ๋ค์ํ ์ฌ์ฉ ์ฌ๋ก์ ์ ์ฉํ ์ ์์ต๋๋ค.
๊ตฌํ ์ธ๋ถ ์ ๋ณด
ํ ํฐ ๋ฒํท ์๊ณ ๋ฆฌ์ฆ์ ๊ตฌํํ๋ ค๋ฉด ๋ฒํท์ ์ํ(ํ์ฌ ํ ํฐ ์ ๋ฐ ๋ง์ง๋ง ์ ๋ฐ์ดํธ ํ์์คํฌํ)๋ฅผ ๊ด๋ฆฌํ๊ณ ๋ค์ด์ค๋ ์์ฒญ์ ์ฒ๋ฆฌํ๋ ๋ก์ง์ ์ ์ฉํด์ผ ํฉ๋๋ค. ๋ค์์ ๊ตฌํ ๋จ๊ณ์ ๊ฐ๋ ์ ๊ฐ์์ ๋๋ค:
- ์ด๊ธฐํ:
- ์ผ๋ฐ์ ์ผ๋ก ๋ค์์ ํฌํจํ๋ ๋ฒํท์ ๋ํ๋ด๋ ๋ฐ์ดํฐ ๊ตฌ์กฐ๋ฅผ ๋ง๋ญ๋๋ค:
- `tokens`: ๋ฒํท์ ํ์ฌ ํ ํฐ ์ (๋ฒํท ํฌ๊ธฐ๋ก ์ด๊ธฐํ).
- `last_refill`: ๋ฒํท์ด ๋ง์ง๋ง์ผ๋ก ๋ณด์ถฉ๋ ์๊ฐ์ ํ์์คํฌํ.
- `bucket_size`: ๋ฒํท์ด ๋ด์ ์ ์๋ ์ต๋ ํ ํฐ ์.
- `refill_rate`: ๋ฒํท์ ํ ํฐ์ด ์ถ๊ฐ๋๋ ์๋ (์: ์ด๋น ํ ํฐ ์).
- ์์ฒญ ์ฒ๋ฆฌ:
- ์์ฒญ์ด ๋์ฐฉํ๋ฉด ํด๋ผ์ด์ธํธ์ ๋ฒํท์ ๊ฒ์ํฉ๋๋ค(์: IP ์ฃผ์ ๋๋ API ํค ๊ธฐ๋ฐ). ๋ฒํท์ด ์์ผ๋ฉด ์๋ก ๋ง๋ญ๋๋ค.
- ๋ง์ง๋ง ๋ณด์ถฉ ์ดํ ๋ฒํท์ ์ถ๊ฐํ ํ ํฐ ์๋ฅผ ๊ณ์ฐํฉ๋๋ค:
- `time_elapsed = current_time - last_refill`
- `tokens_to_add = time_elapsed * refill_rate`
- ๋ฒํท์ ์ ๋ฐ์ดํธํฉ๋๋ค:
- `tokens = min(bucket_size, tokens + tokens_to_add)` (ํ ํฐ ์๊ฐ ๋ฒํท ํฌ๊ธฐ๋ฅผ ์ด๊ณผํ์ง ์๋๋ก ๋ณด์ฅ)
- `last_refill = current_time`
- ์์ฒญ์ ์ฒ๋ฆฌํ ๋งํผ ๋ฒํท์ ์ถฉ๋ถํ ํ ํฐ์ด ์๋์ง ํ์ธํฉ๋๋ค:
- `tokens >= 1`์ธ ๊ฒฝ์ฐ:
- ํ ํฐ ์๋ฅผ ๊ฐ์์ํต๋๋ค: `tokens = tokens - 1`
- ์์ฒญ์ ํ์ฉํฉ๋๋ค.
- ๊ทธ๋ ์ง ์์ ๊ฒฝ์ฐ (`tokens < 1`์ธ ๊ฒฝ์ฐ):
- ์์ฒญ์ ๊ฑฐ๋ถํ๊ฑฐ๋ ๋๊ธฐ์ด์ ์ถ๊ฐํฉ๋๋ค.
- ์๋ ์ ํ ์ด๊ณผ ์ค๋ฅ๋ฅผ ๋ฐํํฉ๋๋ค (์: HTTP ์ํ ์ฝ๋ 429 Too Many Requests).
- ์ ๋ฐ์ดํธ๋ ๋ฒํท ์ํ๋ฅผ ์ ์งํฉ๋๋ค (์: ๋ฐ์ดํฐ๋ฒ ์ด์ค๋ ์บ์์ ์ ์ฅ).
๊ตฌํ ์์ (๊ฐ๋ )
๋ค์์ ํต์ฌ ๋จ๊ณ๋ฅผ ์ค๋ช ํ๊ธฐ ์ํ ๊ฐ๋จํ ๊ฐ๋ ์ ์์ ์ ๋๋ค (ํน์ ์ธ์ด์ ๊ตญํ๋์ง ์์):
class TokenBucket:
def __init__(self, bucket_size, refill_rate):
self.bucket_size = bucket_size
self.refill_rate = refill_rate # ์ด๋น ํ ํฐ ์
self.tokens = bucket_size
self.last_refill = time.time()
def consume(self, tokens_to_consume=1):
self._refill()
if self.tokens >= tokens_to_consume:
self.tokens -= tokens_to_consume
return True # ์์ฒญ ํ์ฉ
else:
return False # ์์ฒญ ๊ฑฐ๋ถ (์๋ ์ ํ ์ด๊ณผ)
def _refill(self):
now = time.time()
time_elapsed = now - self.last_refill
tokens_to_add = time_elapsed * self.refill_rate
self.tokens = min(self.bucket_size, self.tokens + tokens_to_add)
self.last_refill = now
# ์ฌ์ฉ ์์ :
bucket = TokenBucket(bucket_size=10, refill_rate=2) # ์ฉ๋ 10, ์ด๋น 2 ํ ํฐ ๋ณด์ถฉ
if bucket.consume():
# ์์ฒญ ์ฒ๋ฆฌ
print("Request allowed")
else:
# ์๋ ์ ํ ์ด๊ณผ
print("Rate limit exceeded")
์ฐธ๊ณ : ์ด๋ ๊ธฐ๋ณธ์ ์ธ ์์ ์ ๋๋ค. ์ค์ ์ด์ ํ๊ฒฝ์ ์ ์ฉ ๊ฐ๋ฅํ ๊ตฌํ์ ๋์์ฑ, ์์์ฑ ๋ฐ ์ค๋ฅ ์ฒ๋ฆฌ๋ฅผ ๋ค๋ฃจ์ด์ผ ํฉ๋๋ค.
์ฌ๋ฐ๋ฅธ ๋งค๊ฐ๋ณ์ ์ ํ: ๋ฒํท ํฌ๊ธฐ์ ๋ณด์ถฉ ์๋
๋ฒํท ํฌ๊ธฐ์ ๋ณด์ถฉ ์๋์ ์ ์ ํ ๊ฐ์ ์ ํํ๋ ๊ฒ์ ํจ๊ณผ์ ์ธ ์๋ ์ ํ์ ๋งค์ฐ ์ค์ํฉ๋๋ค. ์ต์ ์ ๊ฐ์ ํน์ API, ์๋๋ ์ฌ์ฉ ์ฌ๋ก, ๊ทธ๋ฆฌ๊ณ ์ํ๋ ๋ณดํธ ์์ค์ ๋ฐ๋ผ ๋ฌ๋ผ์ง๋๋ค.
- ๋ฒํท ํฌ๊ธฐ: ๋ฒํท ํฌ๊ธฐ๊ฐ ํด์๋ก ๋ ํฐ ๋ฒ์คํธ ์ฉ๋์ ํ์ฉํฉ๋๋ค. ์ด๋ ๊ฐํ์ ์ธ ํธ๋ํฝ ๊ธ์ฆ์ ๊ฒฝํํ๊ฑฐ๋ ์ฌ์ฉ์๊ฐ ํฉ๋ฒ์ ์ผ๋ก ์ผ๋ จ์ ๋น ๋ฅธ ์์ฒญ์ ํด์ผ ํ๋ API์ ์ ๋ฆฌํ ์ ์์ต๋๋ค. ๊ทธ๋ฌ๋ ๋งค์ฐ ํฐ ๋ฒํท ํฌ๊ธฐ๋ ์ฅ๊ธฐ๊ฐ์ ๋๋ ์ฌ์ฉ์ ํ์ฉํ์ฌ ์๋ ์ ํ์ ๋ชฉ์ ์ ๋ฌด๋ ฅํ์ํฌ ์ ์์ต๋๋ค. ๋ฒํท ํฌ๊ธฐ๋ฅผ ๊ฒฐ์ ํ ๋ ์ฌ์ฉ์์ ์ผ๋ฐ์ ์ธ ๋ฒ์คํธ ํจํด์ ๊ณ ๋ คํ์ญ์์ค. ์๋ฅผ ๋ค์ด, ์ฌ์ง ํธ์ง API๋ ์ฌ์ฉ์๊ฐ ์ฌ๋ฌ ์ด๋ฏธ์ง๋ฅผ ๋น ๋ฅด๊ฒ ์ ๋ก๋ํ ์ ์๋๋ก ๋ ํฐ ๋ฒํท์ด ํ์ํ ์ ์์ต๋๋ค.
- ๋ณด์ถฉ ์๋: ๋ณด์ถฉ ์๋๋ ํ์ฉ๋๋ ํ๊ท ์์ฒญ๋ฅ ์ ๊ฒฐ์ ํฉ๋๋ค. ๋ณด์ถฉ ์๋๊ฐ ๋์์๋ก ๋จ์ ์๊ฐ๋น ๋ ๋ง์ ์์ฒญ์ ํ์ฉํ๋ฉฐ, ๋ฎ์์๋ก ๋ ์ ํ์ ์ ๋๋ค. ๋ณด์ถฉ ์๋๋ API์ ์ฉ๋๊ณผ ์ฌ์ฉ์ ๊ฐ์ ๊ณต์ ์ฑ ์์ค์ ๊ธฐ๋ฐ์ผ๋ก ์ ํํด์ผ ํฉ๋๋ค. API๊ฐ ๋ฆฌ์์ค๋ฅผ ๋ง์ด ์ฌ์ฉํ๋ ๊ฒฝ์ฐ ๋ณด์ถฉ ์๋๋ฅผ ๋ฎ์ถ๋ ๊ฒ์ด ์ข์ต๋๋ค. ๋ํ ํ๋ฆฌ๋ฏธ์ ์ฌ์ฉ์๊ฐ ๋ฌด๋ฃ ์ฌ์ฉ์๋ณด๋ค ๋ ๋์ ๋ณด์ถฉ ์๋๋ฅผ ๊ฐ์ง ์ ์๋๋ก ๋ค์ํ ์ฌ์ฉ์ ๋ฑ๊ธ์ ๊ณ ๋ คํ์ญ์์ค.
์์ ์๋๋ฆฌ์ค:
- ์์ ๋ฏธ๋์ด ํ๋ซํผ์ฉ ๊ณต๊ฐ API: ๋จ์ฉ์ ๋ฐฉ์งํ๊ณ ๋ชจ๋ ์ฌ์ฉ์์ ๊ณต์ ํ ์ ๊ทผ์ ๋ณด์ฅํ๊ธฐ ์ํด ๋ ์์ ๋ฒํท ํฌ๊ธฐ(์: 10-20๊ฐ ์์ฒญ)์ ์ ๋นํ ๋ณด์ถฉ ์๋(์: ์ด๋น 2-5๊ฐ ์์ฒญ)๊ฐ ์ ์ ํ ์ ์์ต๋๋ค.
- ๋ง์ดํฌ๋ก์๋น์ค ํต์ ์ฉ ๋ด๋ถ API: ๋ด๋ถ ๋คํธ์ํฌ๊ฐ ๋น๊ต์ ์์ ์ ์ด๊ณ ๋ง์ดํฌ๋ก์๋น์ค๊ฐ ์ถฉ๋ถํ ์ฉ๋์ ๊ฐ์ง๊ณ ์๋ค๊ณ ๊ฐ์ ํ ๋, ๋ ํฐ ๋ฒํท ํฌ๊ธฐ(์: 50-100๊ฐ ์์ฒญ)์ ๋ ๋์ ๋ณด์ถฉ ์๋(์: ์ด๋น 10-20๊ฐ ์์ฒญ)๊ฐ ์ ํฉํ ์ ์์ต๋๋ค.
- ๊ฒฐ์ ๊ฒ์ดํธ์จ์ด์ฉ API: ์ฌ๊ธฐ๋ฅผ ๋ฐฉ์งํ๊ณ ๋ฌด๋จ ๊ฑฐ๋๋ฅผ ๋ง๊ธฐ ์ํด ๋ ์์ ๋ฒํท ํฌ๊ธฐ(์: 5-10๊ฐ ์์ฒญ)์ ๋ ๋ฎ์ ๋ณด์ถฉ ์๋(์: ์ด๋น 1-2๊ฐ ์์ฒญ)๊ฐ ์ค์ํฉ๋๋ค.
๋ฐ๋ณต์ ์ ๊ทผ: ๋ฒํท ํฌ๊ธฐ์ ๋ณด์ถฉ ์๋์ ๋ํด ํฉ๋ฆฌ์ ์ธ ์ด๊ธฐ ๊ฐ์ผ๋ก ์์ํ ๋ค์, API์ ์ฑ๋ฅ๊ณผ ์ฌ์ฉ ํจํด์ ๋ชจ๋ํฐ๋งํ์ญ์์ค. ์ค์ ๋ฐ์ดํฐ์ ํผ๋๋ฐฑ์ ๊ธฐ๋ฐ์ผ๋ก ํ์์ ๋ฐ๋ผ ๋งค๊ฐ๋ณ์๋ฅผ ์กฐ์ ํ์ญ์์ค.
๋ฒํท ์ํ ์ ์ฅํ๊ธฐ
ํ ํฐ ๋ฒํท ์๊ณ ๋ฆฌ์ฆ์ ๊ฐ ๋ฒํท์ ์ํ(ํ ํฐ ์ ๋ฐ ๋ง์ง๋ง ๋ณด์ถฉ ํ์์คํฌํ)๋ฅผ ์๊ตฌ์ ์ผ๋ก ์ ์ฅํด์ผ ํฉ๋๋ค. ์ฌ๋ฐ๋ฅธ ์ ์ฅ ๋ฉ์ปค๋์ฆ์ ์ ํํ๋ ๊ฒ์ ์ฑ๋ฅ๊ณผ ํ์ฅ์ฑ์ ๋งค์ฐ ์ค์ํฉ๋๋ค.
์ผ๋ฐ์ ์ธ ์ ์ฅ ์ต์ :
- ์ธ๋ฉ๋ชจ๋ฆฌ ์บ์ (์: Redis, Memcached): ๋ฐ์ดํฐ๊ฐ ๋ฉ๋ชจ๋ฆฌ์ ์ ์ฅ๋๋ฏ๋ก ๊ฐ์ฅ ๋น ๋ฅธ ์ฑ๋ฅ์ ์ ๊ณตํฉ๋๋ค. ๋ฎ์ ์ง์ฐ ์๊ฐ์ด ์ค์ํ ๊ณ ํธ๋ํฝ API์ ์ ํฉํฉ๋๋ค. ๊ทธ๋ฌ๋ ์บ์ ์๋ฒ๊ฐ ๋ค์ ์์๋๋ฉด ๋ฐ์ดํฐ๊ฐ ์์ค๋๋ฏ๋ก ๋ณต์ ๋๋ ์์์ฑ ๋ฉ์ปค๋์ฆ ์ฌ์ฉ์ ๊ณ ๋ คํด์ผ ํฉ๋๋ค.
- ๊ด๊ณํ ๋ฐ์ดํฐ๋ฒ ์ด์ค (์: PostgreSQL, MySQL): ๋ด๊ตฌ์ฑ๊ณผ ์ผ๊ด์ฑ์ ์ ๊ณตํฉ๋๋ค. ๋ฐ์ดํฐ ๋ฌด๊ฒฐ์ฑ์ด ๊ฐ์ฅ ์ค์ํ API์ ์ ํฉํฉ๋๋ค. ๊ทธ๋ฌ๋ ๋ฐ์ดํฐ๋ฒ ์ด์ค ์์ ์ ์ธ๋ฉ๋ชจ๋ฆฌ ์บ์ ์์ ๋ณด๋ค ๋๋ฆด ์ ์์ผ๋ฏ๋ก ์ฟผ๋ฆฌ๋ฅผ ์ต์ ํํ๊ณ ๊ฐ๋ฅํ ๊ฒฝ์ฐ ์บ์ฑ ๊ณ์ธต์ ์ฌ์ฉํด์ผ ํฉ๋๋ค.
- NoSQL ๋ฐ์ดํฐ๋ฒ ์ด์ค (์: Cassandra, MongoDB): ํ์ฅ์ฑ๊ณผ ์ ์ฐ์ฑ์ ์ ๊ณตํฉ๋๋ค. ๋งค์ฐ ๋์ ์์ฒญ๋์ ๊ฐ์ง API๋ ๋ฐ์ดํฐ ์คํค๋ง๊ฐ ์งํํ๋ ๊ฒฝ์ฐ์ ์ ํฉํฉ๋๋ค.
๊ณ ๋ ค ์ฌํญ:
- ์ฑ๋ฅ: ์์๋๋ ์ฝ๊ธฐ ๋ฐ ์ฐ๊ธฐ ๋ถํ๋ฅผ ๋ฎ์ ์ง์ฐ ์๊ฐ์ผ๋ก ์ฒ๋ฆฌํ ์ ์๋ ์ ์ฅ ๋ฉ์ปค๋์ฆ์ ์ ํํ์ญ์์ค.
- ํ์ฅ์ฑ: ์ ์ฅ ๋ฉ์ปค๋์ฆ์ด ์ฆ๊ฐํ๋ ํธ๋ํฝ์ ์์ฉํ๊ธฐ ์ํด ์ํ์ ์ผ๋ก ํ์ฅ๋ ์ ์๋์ง ํ์ธํ์ญ์์ค.
- ๋ด๊ตฌ์ฑ: ๋ค์ํ ์ ์ฅ ์ต์ ์ ๋ฐ์ดํฐ ์์ค ๊ฐ๋ฅ์ฑ์ ๊ณ ๋ คํ์ญ์์ค.
- ๋น์ฉ: ๋ค์ํ ์ ์ฅ ์๋ฃจ์ ์ ๋น์ฉ์ ํ๊ฐํ์ญ์์ค.
์๋ ์ ํ ์ด๊ณผ ์ด๋ฒคํธ ์ฒ๋ฆฌํ๊ธฐ
ํด๋ผ์ด์ธํธ๊ฐ ์๋ ์ ํ์ ์ด๊ณผํ๋ฉด ์ด๋ฒคํธ๋ฅผ ์ ์์ ์ผ๋ก ์ฒ๋ฆฌํ๊ณ ์ ์ฉํ ํผ๋๋ฐฑ์ ์ ๊ณตํ๋ ๊ฒ์ด ์ค์ํฉ๋๋ค.
๋ชจ๋ฒ ์ฌ๋ก:
- HTTP ์ํ ์ฝ๋: ํ์ค HTTP ์ํ ์ฝ๋ 429 Too Many Requests๋ฅผ ๋ฐํํฉ๋๋ค.
- Retry-After ํค๋: ์๋ต์ `Retry-After` ํค๋๋ฅผ ํฌํจํ์ฌ ํด๋ผ์ด์ธํธ๊ฐ ๋ค๋ฅธ ์์ฒญ์ ํ๊ธฐ ์ ์ ๊ธฐ๋ค๋ ค์ผ ํ๋ ์๊ฐ(์ด)์ ๋ํ๋ ๋๋ค. ์ด๋ ํด๋ผ์ด์ธํธ๊ฐ ๋ฐ๋ณต์ ์ธ ์์ฒญ์ผ๋ก API๋ฅผ ์๋ํ๋ ๊ฒ์ ๋ฐฉ์งํ๋ ๋ฐ ๋์์ด ๋ฉ๋๋ค.
- ์ ๋ณด์ฑ ์ค๋ฅ ๋ฉ์์ง: ์๋ ์ ํ์ด ์ด๊ณผ๋์์์ ์ค๋ช ํ๊ณ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๋ ๋ฐฉ๋ฒ(์: ์ฌ์๋ ์ ๋๊ธฐ)์ ์ ์ํ๋ ๋ช ํํ๊ณ ๊ฐ๊ฒฐํ ์ค๋ฅ ๋ฉ์์ง๋ฅผ ์ ๊ณตํฉ๋๋ค.
- ๋ก๊น ๋ฐ ๋ชจ๋ํฐ๋ง: ๋ชจ๋ํฐ๋ง ๋ฐ ๋ถ์์ ์ํด ์๋ ์ ํ ์ด๊ณผ ์ด๋ฒคํธ๋ฅผ ๊ธฐ๋กํฉ๋๋ค. ์ด๋ ์ ์ฌ์ ์ธ ๋จ์ฉ์ด๋ ์๋ชป ๊ตฌ์ฑ๋ ํด๋ผ์ด์ธํธ๋ฅผ ์๋ณํ๋ ๋ฐ ๋์์ด ๋ ์ ์์ต๋๋ค.
์๋ต ์์ :
HTTP/1.1 429 Too Many Requests
Content-Type: application/json
Retry-After: 60
{
"error": "์๋ ์ ํ์ ์ด๊ณผํ์ต๋๋ค. 60์ด ํ ๋ค์ ์๋ํด ์ฃผ์ธ์."
}
๊ณ ๊ธ ๊ณ ๋ ค ์ฌํญ
๊ธฐ๋ณธ ๊ตฌํ์ ๋์ด, API ์๋ ์ ํ์ ํจ๊ณผ์ ์ ์ฐ์ฑ์ ๋์ฑ ํฅ์์ํฌ ์ ์๋ ๋ช ๊ฐ์ง ๊ณ ๊ธ ๊ณ ๋ ค ์ฌํญ์ด ์์ต๋๋ค.
- ๊ณ์ธต๋ณ ์๋ ์ ํ: ๋ค์ํ ์ฌ์ฉ์ ๋ฑ๊ธ(์: ๋ฌด๋ฃ, ๊ธฐ๋ณธ, ํ๋ฆฌ๋ฏธ์)์ ๋ํด ๋ค๋ฅธ ์๋ ์ ํ์ ๊ตฌํํฉ๋๋ค. ์ด๋ฅผ ํตํด ๊ตฌ๋ ์๊ธ์ ๋ ๊ธฐํ ๊ธฐ์ค์ ๋ฐ๋ผ ๋ค์ํ ์์ค์ ์๋น์ค๋ฅผ ์ ๊ณตํ ์ ์์ต๋๋ค. ์ฌ๋ฐ๋ฅธ ์๋ ์ ํ์ ์ ์ฉํ๊ธฐ ์ํด ๋ฒํท๊ณผ ํจ๊ป ์ฌ์ฉ์ ๋ฑ๊ธ ์ ๋ณด๋ฅผ ์ ์ฅํฉ๋๋ค.
- ๋์ ์๋ ์ ํ: ์ค์๊ฐ ์์คํ ๋ถํ ๋๋ ๊ธฐํ ์์ธ์ ๋ฐ๋ผ ์๋ ์ ํ์ ๋์ ์ผ๋ก ์กฐ์ ํฉ๋๋ค. ์๋ฅผ ๋ค์ด, ํผํฌ ์๊ฐ๋์๋ ๊ณผ๋ถํ๋ฅผ ๋ฐฉ์งํ๊ธฐ ์ํด ๋ณด์ถฉ ์๋๋ฅผ ์ค์ผ ์ ์์ต๋๋ค. ์ด๋ฅผ ์ํด์๋ ์์คํ ์ฑ๋ฅ์ ๋ชจ๋ํฐ๋งํ๊ณ ๊ทธ์ ๋ฐ๋ผ ์๋ ์ ํ์ ์กฐ์ ํด์ผ ํฉ๋๋ค.
- ๋ถ์ฐ ํ๊ฒฝ์์์ ์๋ ์ ํ: ์ฌ๋ฌ API ์๋ฒ๊ฐ ์๋ ๋ถ์ฐ ํ๊ฒฝ์์๋ ๋ชจ๋ ์๋ฒ์์ ์ผ๊ด๋ ์๋ ์ ํ์ ๋ณด์ฅํ๊ธฐ ์ํด ๋ถ์ฐ ์๋ ์ ํ ์๋ฃจ์ ์ ๊ตฌํํฉ๋๋ค. ๊ณต์ ์ ์ฅ ๋ฉ์ปค๋์ฆ(์: Redis ํด๋ฌ์คํฐ)๊ณผ ์ผ๊ด๋ ํด์ฑ์ ์ฌ์ฉํ์ฌ ์๋ฒ ๊ฐ์ ๋ฒํท์ ๋ถ์ฐ์ํต๋๋ค.
- ์ธ๋ถํ๋ ์๋ ์ ํ: ๋ณต์ก์ฑ๊ณผ ๋ฆฌ์์ค ์๋น๋์ ๋ฐ๋ผ ๋ค๋ฅธ API ์๋ํฌ์ธํธ๋ ๋ฆฌ์์ค์ ๋ํด ๋ค๋ฅด๊ฒ ์๋ ์ ํ์ ์ ์ฉํฉ๋๋ค. ์๋ฅผ ๋ค์ด, ๊ฐ๋จํ ์ฝ๊ธฐ ์ ์ฉ ์๋ํฌ์ธํธ๋ ๋ณต์กํ ์ฐ๊ธฐ ์์ ๋ณด๋ค ๋ ๋์ ์๋ ์ ํ์ ๊ฐ์ง ์ ์์ต๋๋ค.
- IP ๊ธฐ๋ฐ ์๋ ์ ํ vs. ์ฌ์ฉ์ ๊ธฐ๋ฐ ์๋ ์ ํ: IP ์ฃผ์ ๊ธฐ๋ฐ ์๋ ์ ํ๊ณผ ์ฌ์ฉ์ ID ๋๋ API ํค ๊ธฐ๋ฐ ์๋ ์ ํ ๊ฐ์ ์ฅ๋จ์ ์ ๊ณ ๋ คํ์ญ์์ค. IP ๊ธฐ๋ฐ ์๋ ์ ํ์ ํน์ ์์ค๋ก๋ถํฐ์ ์ ์์ ์ธ ํธ๋ํฝ์ ์ฐจ๋จํ๋ ๋ฐ ํจ๊ณผ์ ์ผ ์ ์์ง๋ง, IP ์ฃผ์๋ฅผ ๊ณต์ ํ๋ ํฉ๋ฒ์ ์ธ ์ฌ์ฉ์(์: NAT ๊ฒ์ดํธ์จ์ด ๋ค์ ์ฌ์ฉ์)์๊ฒ๋ ์ํฅ์ ์ค ์ ์์ต๋๋ค. ์ฌ์ฉ์ ๊ธฐ๋ฐ ์๋ ์ ํ์ ๊ฐ๋ณ ์ฌ์ฉ์์ ์ฌ์ฉ๋์ ๋ ์ ํํ๊ฒ ์ ์ดํ ์ ์์ต๋๋ค. ๋ ๊ฐ์ง๋ฅผ ์กฐํฉํ๋ ๊ฒ์ด ์ต์ ์ผ ์ ์์ต๋๋ค.
- API ๊ฒ์ดํธ์จ์ด์์ ํตํฉ: API ๊ฒ์ดํธ์จ์ด(์: Kong, Tyk, Apigee)์ ์๋ ์ ํ ๊ธฐ๋ฅ์ ํ์ฉํ์ฌ ๊ตฌํ ๋ฐ ๊ด๋ฆฌ๋ฅผ ๋จ์ํํ์ญ์์ค. API ๊ฒ์ดํธ์จ์ด๋ ์ข ์ข ๋ด์ฅ๋ ์๋ ์ ํ ๊ธฐ๋ฅ์ ์ ๊ณตํ๋ฉฐ ์ค์ ์ง์ค์ ์ธํฐํ์ด์ค๋ฅผ ํตํด ์๋ ์ ํ์ ๊ตฌ์ฑํ ์ ์๋๋ก ํฉ๋๋ค.
์๋ ์ ํ์ ๋ํ ๊ธ๋ก๋ฒ ๊ด์
๊ธ๋ก๋ฒ ์ฌ์ฉ์๋ฅผ ์ํ API ์๋ ์ ํ์ ์ค๊ณํ๊ณ ๊ตฌํํ ๋ ๋ค์ ์ฌํญ์ ๊ณ ๋ คํ์ญ์์ค:
- ์๊ฐ๋: ๋ณด์ถฉ ๊ฐ๊ฒฉ์ ์ค์ ํ ๋ ๋ค๋ฅธ ์๊ฐ๋๋ฅผ ์ ์ํ์ญ์์ค. ์ผ๊ด์ฑ์ ์ํด UTC ํ์์คํฌํ๋ฅผ ์ฌ์ฉํ๋ ๊ฒ์ ๊ณ ๋ คํ์ญ์์ค.
- ๋คํธ์ํฌ ์ง์ฐ ์๊ฐ: ๋คํธ์ํฌ ์ง์ฐ ์๊ฐ์ ์ง์ญ๋ง๋ค ํฌ๊ฒ ๋ค๋ฅผ ์ ์์ต๋๋ค. ์๊ฒฉ ์ง์ญ์ ์ฌ์ฉ์์๊ฒ ์๋์น ์๊ฒ ๋ถ์ด์ต์ ์ฃผ์ง ์๋๋ก ์๋ ์ ํ์ ์ค์ ํ ๋ ์ ์ฌ์ ์ธ ์ง์ฐ ์๊ฐ์ ๊ณ ๋ คํ์ญ์์ค.
- ์ง์ญ ๊ท์ : API ์ฌ์ฉ์ ์ํฅ์ ๋ฏธ์น ์ ์๋ ์ง์ญ ๊ท์ ์ด๋ ๊ท์ ์ค์ ์๊ตฌ ์ฌํญ์ ์ธ์งํ์ญ์์ค. ์๋ฅผ ๋ค์ด, ์ผ๋ถ ์ง์ญ์๋ ์์งํ๊ฑฐ๋ ์ฒ๋ฆฌํ ์ ์๋ ๋ฐ์ดํฐ์ ์์ ์ ํํ๋ ๋ฐ์ดํฐ ํ๋ผ์ด๋ฒ์ ๋ฒ์ด ์์ ์ ์์ต๋๋ค.
- ์ฝํ ์ธ ์ ์ก ๋คํธ์ํฌ (CDN): CDN์ ํ์ฉํ์ฌ API ์ฝํ ์ธ ๋ฅผ ๋ฐฐํฌํ๊ณ ๋ค๋ฅธ ์ง์ญ์ ์ฌ์ฉ์๋ค์ ์ํ ์ง์ฐ ์๊ฐ์ ์ค์ด์ญ์์ค.
- ์ธ์ด ๋ฐ ํ์งํ: ๊ธ๋ก๋ฒ ์ฌ์ฉ์๋ฅผ ์ํด ์ค๋ฅ ๋ฉ์์ง์ ๋ฌธ์๋ฅผ ์ฌ๋ฌ ์ธ์ด๋ก ์ ๊ณตํ์ญ์์ค.
๊ฒฐ๋ก
API ์๋ ์ ํ์ API๋ฅผ ๋จ์ฉ์ผ๋ก๋ถํฐ ๋ณดํธํ๊ณ ์์ ์ฑ๊ณผ ๊ฐ์ฉ์ฑ์ ๋ณด์ฅํ๊ธฐ ์ํ ํ์์ ์ธ ๊ดํ์ ๋๋ค. ํ ํฐ ๋ฒํท ์๊ณ ๋ฆฌ์ฆ์ ๋ค์ํ ์๋๋ฆฌ์ค์์ ์๋ ์ ํ์ ๊ตฌํํ๊ธฐ ์ํ ์ ์ฐํ๊ณ ํจ๊ณผ์ ์ธ ์๋ฃจ์ ์ ์ ๊ณตํฉ๋๋ค. ๋ฒํท ํฌ๊ธฐ์ ๋ณด์ถฉ ์๋๋ฅผ ์ ์คํ๊ฒ ์ ํํ๊ณ , ๋ฒํท ์ํ๋ฅผ ํจ์จ์ ์ผ๋ก ์ ์ฅํ๋ฉฐ, ์๋ ์ ํ ์ด๊ณผ ์ด๋ฒคํธ๋ฅผ ์ ์์ ์ผ๋ก ์ฒ๋ฆฌํจ์ผ๋ก์จ, API๋ฅผ ๋ณดํธํ๊ณ ์ ์ธ๊ณ ์ฌ์ฉ์์๊ฒ ๊ธ์ ์ ์ธ ์ฌ์ฉ์ ๊ฒฝํ์ ์ ๊ณตํ๋ ๊ฐ๋ ฅํ๊ณ ํ์ฅ ๊ฐ๋ฅํ ์๋ ์ ํ ์์คํ ์ ๋ง๋ค ์ ์์ต๋๋ค. ๋ณํํ๋ ํธ๋ํฝ ํจํด๊ณผ ๋ณด์ ์ํ์ ์ ์ํ๊ธฐ ์ํด API ์ฌ์ฉ๋์ ์ง์์ ์ผ๋ก ๋ชจ๋ํฐ๋งํ๊ณ ํ์์ ๋ฐ๋ผ ์๋ ์ ํ ๋งค๊ฐ๋ณ์๋ฅผ ์กฐ์ ํ๋ ๊ฒ์ ์์ง ๋ง์ญ์์ค.
ํ ํฐ ๋ฒํท ์๊ณ ๋ฆฌ์ฆ์ ์๋ฆฌ์ ๊ตฌํ ์ธ๋ถ ์ ๋ณด๋ฅผ ์ดํดํจ์ผ๋ก์จ API๋ฅผ ํจ๊ณผ์ ์ผ๋ก ๋ณดํธํ๊ณ ์ ์ธ๊ณ ์ฌ์ฉ์์๊ฒ ์๋น์ค๋ฅผ ์ ๊ณตํ๋ ์์ ์ ์ด๊ณ ํ์ฅ ๊ฐ๋ฅํ ์ ํ๋ฆฌ์ผ์ด์ ์ ๊ตฌ์ถํ ์ ์์ต๋๋ค.